﻿using _RobotInspection.DTO;
using _RobotInspection.Entities;
using _RobotInspection.Interfaces;
using _RobotInspection.Models;
using Microsoft.AspNetCore.Mvc;
using RobotInspection.Entities;
using SqlSugar;
using System.Numerics;
using System.Security;

namespace _RobotInspection.Services
{
    /// <summary>
    /// 用户相关功能实现服务类
    /// </summary>
    public class UserService : IUserService
    {
        private readonly ISqlSugarClient _db;
        private readonly ILogger<UserService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="db"></param>
        /// <param name="logger"></param>
        public UserService(ISqlSugarClient db, ILogger<UserService> logger)
        {
            _db = db;
            _logger = logger;
        }

        // 用户数据管理
        /// <summary>
        /// 异步查询所有用户
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResponse<List<UserDto>>> GetUsersAsync()
        {
            try
            {
                var userList = await _db.Queryable<users>().ToListAsync();
                var userDtoList = new List<UserDto>();
                for (int i = 0; i < userList.Count; i++)
                {
                    UserDto userDto = UserRepository.ConvertUserToUserDto(userList[i]);
                    userDtoList.Add(userDto);
                }
                return ApiResponse<List<UserDto>>.Success(userDtoList, null, userList.Count);
            }
            catch (Exception ex) 
            {
                return ApiResponse<List<UserDto>>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步分页查询用户
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResponse<UserPagedResultDto>> GetUsersPagedAsync(UserPagedQueryDto queryDto)
        {
            // 执行数据查询
            try
            {
                var queryable = _db.Queryable<users>();

                //按要求添加查询条件
                if (!string.IsNullOrWhiteSpace(queryDto.RealName))
                {
                    queryable = queryable.Where(u => u.real_name.Contains(queryDto.RealName));
                }
                if (queryDto.Role.HasValue)
                {
                    queryable = queryable.Where(u => u.prmission == queryDto.Role);
                }
                if (queryDto.Status.HasValue)
                {
                    queryable = queryable.Where(u => u.status == queryDto.Status);
                }

                // 获取总记录数
                var totalCount = await queryable.CountAsync();

                var userList = await queryable
                    .OrderBy(u => u.created_at, OrderByType.Desc)
                    .ToPageListAsync(queryDto.PageIndex, queryDto.PageSize);

                //转换为UserDto
                var userDtoList = new List<UserDto>();
                for (int i = 0; i < userList.Count; i++)
                {
                    UserDto userDto = UserRepository.ConvertUserToUserDto(userList[i]);
                    userDtoList.Add(userDto);
                }

                //判断总页数
                var totalPages = 0;
                if (totalCount % queryDto.PageSize > 0)
                {
                    totalPages = totalCount / queryDto.PageSize + 1;
                }
                else
                {
                    totalPages = totalCount / queryDto.PageSize;
                }

                //准备返回数据结构
                var userPagedResultDto = new UserPagedResultDto
                {
                    UserDtoList = userDtoList,
                    TotalCount = totalCount,
                    TotalPages = totalPages,
                    CurrentPage = queryDto.PageIndex,
                    PageSize = queryDto.PageSize,
                    HasPreviousPage = queryDto.PageIndex > 1,
                    HasNextPage = queryDto.PageIndex < totalPages
                };

                var message = $"查询到用户总数：{totalCount}";
                return ApiResponse<UserPagedResultDto>.Success(userPagedResultDto, message, totalCount);
            }
            catch (Exception ex)
            {
                return ApiResponse<UserPagedResultDto>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步按ID查询用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        public async Task<ApiResponse<UserDto>> GetUserByIdAsync(long id)
        {
            // 业务逻辑验证
            if (id <= 0)
            {
                throw new BusinessException(400, "查询失败：用户ID不合法");
            }

            // 执行数据查询
            try
            {
                var user = await _db.Queryable<users>().Where(i => i.id == id).ToListAsync();
                if (user.Count == 1)
                {
                    var userDto = UserRepository.ConvertUserToUserDto(user[0]);
                    return ApiResponse<UserDto>.Success(userDto, null);
                }
                else
                {
                    return ApiResponse<UserDto>.Error("查询失败：ID不存在", 400);
                }
            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步按用户名查询用户
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        public async Task<ApiResponse<UserDto>> GetUserByUserNameAsync(string userName)
        {
            if (userName == "")
            {
                throw new BusinessException(400, "查询失败：用户名为空");
            }
            try
            {
                var userList = await _db.Queryable<users>().Where(i => i.username == userName).ToListAsync();
                if (userList.Count == 1)
                {
                    var userDto = UserRepository.ConvertUserToUserDto(userList[0]);
                    return ApiResponse<UserDto>.Success(userDto, null);
                }
                else
                {
                    return ApiResponse<UserDto>.Error("查询失败：用户名不唯一", 400);
                }
            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步修改用户的用户名
        /// </summary>
        /// <param name="id"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public async Task<ApiResponse<UserDto>> UpdateUserNameAsync(long id, string userName)
        {
            try
            {
                var userList = await _db.Queryable<users>().Where(i => i.id == id).ToListAsync();
                if (userList.Count == 1)
                {
                    var result = await _db.Updateable<users>().SetColumns(u => new users { username = userName, updated_at = DateTime.Now }).Where(i => i.id == id).ExecuteReturnEntityAsync();
                    var userDto = UserRepository.ConvertUserToUserDto(result);
                    return ApiResponse<UserDto>.Success(userDto, "修改成功");
                }
                else
                {
                    return ApiResponse<UserDto>.Error("修改失败：用户id不存在或错误", 400);

                }
            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"修改失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步修改用户的密码
        /// </summary>
        /// <param name="id"></param>
        /// <param name="userPassword"></param>
        /// <returns></returns>
        public async Task<ApiResponse<UserDto>> UpdateUserPasswordAsync(long id, string userPassword)
        {
            try
            {
                var userList = await _db.Queryable<users>().Where(i => i.id == id).ToListAsync();
                if (userList.Count == 1)
                {
                    var result = await _db.Updateable<users>().SetColumns(u => new users { user_password = userPassword, updated_at = DateTime.Now }).Where(i => i.id == id).ExecuteReturnEntityAsync();
                    var userDto = UserRepository.ConvertUserToUserDto(result);
                    return ApiResponse<UserDto>.Success(userDto, "修改成功");
                }
                else
                {
                    return ApiResponse<UserDto>.Error("修改失败：用户id不存在或错误", 400);
                }
            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"修改失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步修改用户的权限
        /// </summary>
        /// <param name="id"></param>
        /// <param name="permission"></param>
        /// <returns></returns>
        public async Task<ApiResponse<UserDto>> UpdateUserPermissionAsync(long id, byte permission)
        {
            try
            {
                var userList = await _db.Queryable<users>().Where(i => i.id == id).ToListAsync();
                if (userList.Count == 1)
                {
                    var result = await _db.Updateable<users>().SetColumns(u => new users { prmission = permission, updated_at = DateTime.Now }).Where(i => i.id == id).ExecuteReturnEntityAsync();
                    var userDto = UserRepository.ConvertUserToUserDto(result);
                    return ApiResponse<UserDto>.Success(userDto, "修改成功");
                }
                else
                {
                    return ApiResponse<UserDto>.Error("修改失败，用户id不存在或错误", 400);

                }
            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"修改失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步修改用户的状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public async Task<ApiResponse<UserDto>> UpdateUserStatusAsync(long id, byte status)
        {
            if (status != 0 && status != 1)
            {
                return ApiResponse<UserDto>.Error($"输入错误：用户状态必须是0或1", 400);
            }
            try
            {
                var userList = await _db.Queryable<users>().Where(i => i.id == id).ToListAsync();
                if (userList.Count == 1)
                {
                    var result = await _db.Updateable<users>().SetColumns(u => new users { status = status, updated_at = DateTime.Now }).Where(i => i.id == id).ExecuteReturnEntityAsync();
                    var userDto = UserRepository.ConvertUserToUserDto(result);
                    return ApiResponse<UserDto>.Success(userDto, "修改成功");
                }
                else
                {
                    return ApiResponse<UserDto>.Error("修改失败：用户id不存在或错误", 400);

                }
            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"修改失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResponse<UserDto?>> DeleteUserAsync(long id)
        {
            //检验id是否合法
            if (id <= 0) 
            { 
                throw new BusinessException(400, "查询失败：设备ID无效"); 
            }

            try
            {
                //检验user是否存在
                var userNumber = await _db.Queryable<users>().Where(i => i.id == id).CountAsync();
                if (userNumber == 0) 
                { 
                    return ApiResponse<UserDto?>.Error("删除失败：用户id不存在或错误", 400); 
                }

                //检验并删除点检计划-用户关联项
                var puNumber = await _db.Queryable<plan_user_relations>().Where(pu => pu.user_id == id).CountAsync();
                if (puNumber > 0)
                { 
                    await _db.Deleteable<plan_user_relations>().Where(pu => pu.user_id == id).ExecuteCommandAsync(); 
                }

                //检验并删除设备-用户关联项
                var euNumber = await _db.Queryable<equipment_user_relations>().Where(eu => eu.user_id == id).CountAsync();
                if (euNumber > 0) 
                { 
                    await _db.Deleteable<equipment_user_relations>().Where(eu => eu.user_id == id).ExecuteCommandAsync(); 
                }

                //修改用户
                await _db.Deleteable<users>().Where(i => i.id == id).ExecuteCommandAsync();
                
                //总结上述操作
                string message = $"删除点检计划-用户关联项{puNumber}个，设备-用户关联项删除{euNumber}个，用户删除成功";

                return ApiResponse<UserDto?>.Success(null, message);

            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto?>.Error($"删除失败：{ex.Message}", 500);
            }
        }

        // 用户管理业务逻辑
        /// <summary>
        /// 用户登录验证
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPassword"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        public async Task<ApiResponse<UserDto>> LoginAsync(string userName, string userPassword)
        {
            // 添加业务逻辑验证
            if (string.IsNullOrWhiteSpace(userName))
            {
                throw new BusinessException(400, "用户登录验证失败：用户名不能为空");
            }

            if (string.IsNullOrWhiteSpace(userPassword))
            {
                throw new BusinessException(400, "用户登录验证失败：密码不能为空");
            }

            try
            {
                var userList = await _db.Queryable<users>().Where(i => i.username == userName).ToListAsync();
                switch (userList.Count)
                {
                    case 1:
                        {
                            if (userList[0].user_password == userPassword)
                            {
                                var userDto = UserRepository.ConvertUserToUserDto(userList[0]);
                                return ApiResponse<UserDto>.Success(userDto, "登录成功");
                            }
                            else
                            {
                                return ApiResponse<UserDto>.Error("用户登录验证失败：密码错误", 400);
                            }
                        }
                    default:
                        {
                            return ApiResponse<UserDto>.Error("用户登录验证失败：用户名错误", 400);
                        }
                }

            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"用户登录验证失败：{ex.Message}", 500);
            }


        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResponse<UserDto>> RegisterAsync(UserInsertDto queryDto)
        {
            // 检验必要参数
            if (!string.IsNullOrWhiteSpace(queryDto.UserName))
            {
                return ApiResponse<UserDto>.Error("用户注册失败：需要用户名", 400);
            }
            if (!string.IsNullOrWhiteSpace(queryDto.UserPassword))
            {
                return ApiResponse<UserDto>.Error("用户注册失败：需要密码", 400);
            }
            if (!string.IsNullOrWhiteSpace(queryDto.RealName))
            {
                return ApiResponse<UserDto>.Error("用户注册失败：需要真名", 400);
            }

            try
            {
                // 检验用户名是否唯一
                var userNumber = await _db.Queryable<users>().Where(i => i.username == queryDto.UserName).CountAsync();
                if (userNumber != 0)
                {
                    return ApiResponse<UserDto>.Error($"用户注册失败，用户名不唯一", 400);
                }

                // 创建user数据
                var user = new users
                {
                    username = queryDto.UserName,
                    user_password = queryDto.UserPassword,
                    real_name = queryDto.RealName,
                    phone = queryDto.Phone ?? "",
                    email = queryDto.Email ?? "",
                    prmission = queryDto.Permission ?? 1,
                    status = queryDto.Status ?? 1,
                    created_at = DateTime.Now,
                    updated_at = DateTime.Now
                };

                // 插入数据
                var result = await _db.Insertable(user).ExecuteReturnEntityAsync();
                var userDto = UserRepository.ConvertUserToUserDto(result);
                return ApiResponse<UserDto>.Success(userDto, "用户注册成功");
            }
            catch (Exception ex)
            {
                return ApiResponse<UserDto>.Error($"用户注册失败：{ex.Message}", 500);
            }

        }

        /// <summary>
        /// 为用户绑定设备
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="EquipmentId"></param>
        /// <returns></returns>
        public async Task<ActionResult<ApiResponse<bool>>> EquipmentBindingUser(int UserId, List<long> EquipmentId)
        {
            if (EquipmentId == null || EquipmentId.Count == 0)
                return new BadRequestObjectResult(ApiResponse<object>.Error("设备ID列表不能为空"));

            try
            {
                // 验证用户是否存在
                var user = await _db.Queryable<users>()
                                    .Where(u => u.id == UserId && u.status == 1)
                                    .FirstAsync();
                if (user == null)
                {
                    return new BadRequestObjectResult(ApiResponse<object>.Error($"用户ID {UserId} 不存在或已停用"));
                }

                // 查询数据库中实际存在的设备ID
                var existingIds = await _db.Queryable<equipment>()
                                           .Where(e => EquipmentId.Contains(e.id))
                                           .Select(e => e.id)
                                           .ToListAsync();
                // 找出不存在的ID
                var missingIds = EquipmentId.Except(existingIds).ToList();
                if (missingIds.Any())
                {
                    string missingList = string.Join(",", missingIds);
                    return new BadRequestObjectResult(ApiResponse<object>.Error($"以下设备ID不存在: {missingList}"));
                }

                // 使用事务确保数据一致性
                var transactionResult = await _db.Ado.UseTranAsync(async () =>
                {
                    // 先删除该用户的所有设备绑定关系
                    await _db.Deleteable<equipment_user_relations>()
                              .Where(r => r.user_id == UserId)
                              .ExecuteCommandAsync();

                    // 创建新的绑定关系
                    var relations = existingIds.Select(equipId => new equipment_user_relations
                    {
                        equipment_id = equipId,
                        user_id = UserId,
                        is_primary = 0, // 默认不是主要负责人
                        is_active = 1   // 默认关系有效
                    }).ToList();

                    // 批量插入新的绑定关系
                    await _db.Insertable(relations).ExecuteCommandAsync();
                });

                if (transactionResult.IsSuccess)
                {
                    return new OkObjectResult(ApiResponse<bool>.Success(true, $"成功为用户ID {UserId} 绑定 {existingIds.Count} 个设备"));
                }
                else
                {
                    return new OkObjectResult(ApiResponse<bool>.Error($"绑定设备失败: {transactionResult.ErrorMessage}", 500));
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"为用户ID {UserId} 绑定设备时发生错误");
                return new OkObjectResult(ApiResponse<bool>.Error($"绑定设备失败: {ex.Message}", 500));
            }
        }

    }

    /// <summary>
    /// UserService使用的一些静态函数
    /// </summary>
    public static class UserRepository
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static UserDto ConvertUserToUserDto(users user)
        {
            var userDto = new UserDto
            {
                Id = user.id,
                UserName = user.username,
                RealName = user.real_name,
                Role = user.prmission,
                Status = (byte)(user.status ?? 1),
                RegisterTime = user.created_at
            };
            return userDto;
        }
    }
}
